﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;

namespace HYRevitCode.ShortPathSuite
{
	public class UndirectGraph
	{
		public List<Vertex> Vertexs
		{
			get
			{
				return this.vertexs;
			}
			private set
			{
				this.vertexs = value;
			}
		}

		public UndirectGraph()
		{
			this.Vertexs = new List<Vertex>();
			this.edges = new List<Edge>();
		}

		public UndirectGraph(List<Vertex> lstVertexs, List<Edge> lstEdges)
		{
			this.Vertexs = new List<Vertex>();
			this.edges = new List<Edge>();
			foreach (Vertex item in lstVertexs)
			{
				this.Vertexs.Add(item);
			}
			foreach (Edge item2 in lstEdges)
			{
				this.edges.Add(item2);
			}
		}

		private Vertex AddVertex(XYZ pt)
		{
			int num = this.Vertexs.FindIndex((Vertex vertex) => vertex.Point.IsAlmostEqualTo(pt, 0.001));
			if (-1 == num)
			{
				Vertex vertex2 = new Vertex(this.GetNewVertexID(), pt);
				this.Vertexs.Add(vertex2);
				return vertex2;
			}
			return this.Vertexs[num];
		}

		public Vertex GetVertexByID(long id)
		{
			int num = this.Vertexs.FindIndex((Vertex vertex) => vertex.ID == id);
			if (-1 == num)
			{
				return null;
			}
			return this.Vertexs[num];
		}

		public Vertex GetVertexByPoint(XYZ pt)
		{
			int num = this.Vertexs.FindIndex((Vertex vertex) => vertex.Point.IsAlmostEqualTo(pt, 0.001));
			if (-1 == num)
			{
				return null;
			}
			return this.Vertexs[num];
		}

		public long GetVertexIDByPoint(XYZ pt)
		{
			int num = this.Vertexs.FindIndex((Vertex vertex) => vertex.Point.IsAlmostEqualTo(pt, 0.001));
			if (-1 == num)
			{
				return -1L;
			}
			return this.Vertexs[num].ID;
		}

		public void ResetVertexVisited()
		{
			foreach (Vertex vertex in this.Vertexs)
			{
				vertex.Visited = false;
			}
		}

		public List<Vertex>.Enumerator VertexEnumerator()
		{
			return this.Vertexs.GetEnumerator();
		}

		private long GetNewVertexID()
		{
			return (long)(this.Vertexs.Count + 1);
		}

		public void AddEdge(XYZ startPt, XYZ endPt, ElementId elementId)
		{
			if (this.EdgeIsExisted(startPt, endPt, elementId))
			{
				return;
			}
			long newEdgeID = this.GetNewEdgeID();
			Vertex vertex = this.AddVertex(startPt);
			if (vertex != null && !vertex.EdgeList.Contains(newEdgeID))
			{
				vertex.EdgeList.Add(newEdgeID);
			}
			Vertex vertex2 = this.AddVertex(endPt);
			if (vertex2 != null && !vertex2.EdgeList.Contains(newEdgeID))
			{
				vertex2.EdgeList.Add(newEdgeID);
			}
			double weight = startPt.DistanceTo(endPt);
			Edge item = new Edge(newEdgeID, elementId, vertex.ID, vertex2.ID, weight);
			this.edges.Add(item);
		}

		public Edge GetEdgeByID(long id)
		{
			int num = this.edges.FindIndex((Edge edge) => edge.ID == id);
			if (-1 == num)
			{
				return null;
			}
			return this.edges[num];
		}

		public List<Edge>.Enumerator EdgeEnumerator()
		{
			return this.edges.GetEnumerator();
		}

		private long GetNewEdgeID()
		{
			return (long)(this.edges.Count + 1);
		}

		private bool EdgeIsExisted(XYZ startPt, XYZ endPt, ElementId elementId)
		{
			long fromID = this.GetVertexIDByPoint(startPt);
			long toID = this.GetVertexIDByPoint(endPt);
			if (fromID == -1L || toID == -1L)
			{
				return false;
			}
			int num = this.edges.FindIndex((Edge edge) => edge.ElementID == elementId && ((edge.FromID == fromID && edge.ToID == toID) || (edge.FromID == toID && edge.ToID == fromID)));
			return -1 != num;
		}

		private List<Vertex> vertexs;

		private List<Edge> edges;
	}
}
